package cn.tsmchina.one.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import cn.tsmchina.one.domain.recommendation.Recommend;

/**
 * @author yue
 * @date 2013-3-28下午5:08:39
 * @param <T>
 */
@SuppressWarnings("unchecked")
public abstract class BaseDaoSupport<T>
{

	@Autowired
	private SessionFactory sessionFactory;

	private Class<T> entityClass = (Class<T>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);

	/**
	 * 得到session
	 * @return
	 * @date 2013-3-28 下午3:56:14
	 * @author yue
	 */
	private Session session()
	{
		return sessionFactory.getCurrentSession();
	}

	/**
	 * 添加
	 * @param entity
	 * @return
	 * @date 2013-3-28 下午3:56:34
	 * @author yue
	 */
	protected Serializable add(T entity)
	{
		return session().save(entity);
	}
	
	/**
	 * 添加
	 * @param entity
	 * @return
	 * @date 2013-3-28 下午3:56:34
	 * @author yue
	 */
	protected Long[] add(List<T> lists)
	{
		int size = lists.size();
		Long[] array = new  Long[size];
		for (int i = 0; i <size; i++)
			array[i] = (Long) session().save(lists.get(i));
		return array;
	}

	/**
	 * 更新
	 * @param entity
	 * @date 2013-3-28 下午3:57:00
	 * @author yue
	 */
	protected void update(T entity)
	{
		session().update(entity);
	}

	/**
	 * 更新
	 * @author  YUE
	 * @date 2013-6-3 下午4:09:59
	 * @param hql
	 * @param hqlMap
	 * @return
	 */
	protected int update(String hql,Map<String, Object> hqlMap)
	{
		return executeUpdate(hql, hqlMap);
	}
	
	/**
	 * 删除
	 * @author  YUE
	 * @date 2013-6-3 下午2:57:13
	 * @param id
	 * @return
	 */
	protected int delete(Long id)
	{
		String hql = "delete from "+entityClass.getSimpleName()+" where id = :id";
		Map<String, Object> hqlMap = new HashMap<String, Object>();
		hqlMap.put("id", id);
		return executeUpdate(hql, hqlMap);
	}
	
	
	/*protected int delete(Long id)
	{
		String hql = "delete from "+entityClass.getSimpleName()+" where id = ?";
		return executeUpdate(hql, id);
	}*/
	
	/**
	 * 批量删除
	 * @author  YUE
	 * @date 2013-6-3 下午2:58:53
	 * @param id
	 * @return
	 */
	protected int delete(Integer[] id )
	{
		String hql = "delete from "+entityClass.getSimpleName()+" where id in (:id)";
		Map<String, Object> hqlMap = new HashMap<String, Object>();
		hqlMap.put("id", id);
		return executeUpdate(hql, hqlMap);
	}
	
	protected void delete(Serializable id)
	{
		session().delete(findById(id));
	}


	/**
	 * 返回唯一结果
	 * @param hql
	 * @return
	 * @date 2013-3-28 下午3:59:34
	 * @author yue
	 */
	protected Object find(String hql)
	{
		return query(hql).uniqueResult();
	}
	

	/**
	 * 返回唯一结果
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午3:59:51
	 * @author yue
	 */
	protected Object find(String hql, Map<String, Object> hqlMap)
	{
		return query(hql, hqlMap).uniqueResult();
	}
	
	/**
	 * 返回唯一结果
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午3:59:51
	 * @author yue
	 */
	protected Object find(String hql,Object...objects)
	{
		return query(hql, objects).uniqueResult();
	}
	

	/**
	 * 返回一个 实体
	 * @param id
	 * @return
	 * @date 2013-3-28 下午4:00:25
	 * @author yue
	 */
	protected T findById(Serializable id)
	{
		return (T) session().get(entityClass, id);
	}

	/**
	 * 执行增删改
	 * @param hql
	 * @return
	 * @date 2013-3-28 下午4:02:06
	 * @author yue
	 */
	protected int exexuteUpdate(String hql)
	{
		return query(hql).executeUpdate();
	}

	/**
	 * 执行增删改
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:02:59
	 * @author yue
	 */
	protected int executeUpdate(String hql, Map<String, Object> hqlMap)
	{
		
		return query(hql, hqlMap).executeUpdate();
	}
	
	/**
	 * 执行增删改
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:02:59
	 * @author yue
	 */
	protected int executeUpdate(String hql,Object...objects)
	{
		
		return query(hql, objects).executeUpdate();
	}
	
	/**
	 * 返回结果集合
	 * @return
	 * @date 2013-3-28 下午4:03:03
	 * @author yue
	 */
	protected List<T> lists()
	{
		return query("from " + entityClass.getSimpleName()).list();
	}
	

	/**
	 * 返回结果集合
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:20:33
	 * @author yue
	 */
	protected List<T> lists(int page, int size)
	{
		System.out.println(page);
		System.out.println(size);
		System.out.println(entityClass.getSimpleName());
		query("from " + entityClass.getSimpleName()).list();
		return query("from " + entityClass.getSimpleName(), page, size).list();
	}
	

	/**
	 * 返回结果集合
	 * @param hql
	 * @return
	 * @date 2013-3-28 下午4:03:40
	 * @author yue
	 */
	protected List<T> lists(String hql)
	{
		return query(hql).list();
	}

	/**
	 * 返回结果集合
	 * @param hql
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:03:46
	 * @author yue
	 */
	protected List<T> lists(String hql, int page, int size)
	{
		return query(hql, page, size).list();
	}

	/**
	 * 返回结果集合
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:05:06
	 * @author yue
	 */
	protected List<T> lists(String hql, Map<String, Object> hqlMap)
	{
		return query(hql, hqlMap).list();
	}
	
	/**
	 * 返回结果集合
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:05:06
	 * @author yue
	 */
	protected List<T> lists(String hql,Object...objects)
	{
		return query(hql, objects).list();
	}

	/**
	 * 返回结果集合
	 * @param hql
	 * @param map
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:05:17
	 * @author yue
	 */
	protected List<T> lists(String hql, Map<String, Object> hqlMap, int page,int size)
	{
		return query(hql, hqlMap, page, size).list();
	}
	
	/**
	 * 返回结果集合
	 * @param hql
	 * @param map
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:05:17
	 * @author yue
	 */
	protected List<T> lists(String hql,int page,int size,Object...objects)
	{
		return query(hql,page, size,objects).list();
	}

	/**
	 * 返回结果数组
	 * 
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-29 上午11:14:19
	 * @author yue
	 */
	protected Object[] arrays(String hql, Map<String, Object> hqlMap)
	{
		List<?> list = query(hql, hqlMap).list();
		Object[] array = new Object[list.size()];
		for (int i = 0; i < array.length; i++)
			array[i] = (Object)list.get(i);
		return array;
	}
	
	protected List<?> arrays(String hql)
	{
		List<?> list = query(hql).list();
		return list;
	}
	
	/**
	 * 返回结果数组
	 * 
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-29 上午11:14:19
	 * @author yue
	 */
	protected Object[] arrays(String hql,Object...objects)
	{
		List<?> list = query(hql, objects).list();
		Object[] array = new Object[list.size()];
		for (int i = 0; i < array.length; i++)
			array[i] = (Object)list.get(i);
		return array;
	}

	/**
	 * 返回有多少条数
	 * @return
	 * @date 2013-3-28 下午4:05:43
	 * @author yue
	 */
	protected int count()
	{
		String hql = "select count(id) from " + entityClass.getSimpleName();
		return Integer.parseInt(String.valueOf(find(hql)));
	}
	

	/**
	 * 有多少条数
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:07:46
	 * @author yue
	 */
	protected int count(String hql, Map<String, Object> hqlMap)
	{
		Integer a = Integer.parseInt(String.valueOf(find(hql, hqlMap)));
		return a;
	}
	
	/**
	 * 有多少条数
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:07:46
	 * @author yue
	 */
	protected int count(String hql,Object...objects)
	{
		return Integer.parseInt(String.valueOf(find(hql, objects)));
	}
	
	/**
	 * 有多少条数
	 * @author  YUE
	 * @date 2013-4-26 下午3:24:28
	 * @param hql
	 * @return
	 */
	protected int count(String hql)
	{
		return Integer.parseInt(String.valueOf(find(hql)));
	}

	/**
	 * 创建Query
	 * 
	 * @param hql
	 * @return
	 * @date 2013-3-28 下午4:08:08
	 * @author yue
	 */
	private Query query(String hql)
	{
		return session().createQuery(hql);
	}

	/**
	 * 设置参数
	 * @param hql
	 * @param hqlMap
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:08:32
	 * @author yue
	 */
	private Query query(String hql, Map<String, Object> hqlMap, int page,int size)
	{
		return query(hql, hqlMap).setFirstResult((page - 1) * size).setMaxResults(size);
	}
	
	/**
	 * 设置参数
	 * @param hql
	 * @param hqlMap
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:08:32
	 * @author yue
	 */
	private Query query(String hql,int page,int size,Object...objects)
	{
		return query(hql, objects).setFirstResult((page - 1) * size).setMaxResults(size);
	}

	/**
	 * 设置参数
	 * @param hql
	 * @param hqlMap
	 * @return
	 * @date 2013-3-28 下午4:09:02
	 * @author yue
	 */
	private Query query(String hql, Map<String, Object> hqlMap)
	{
		Query query = query(hql);
		if(null != hqlMap)
			query.setProperties(hqlMap);
		return query;
	}
	
	/**
	 * 设置参数
	 * @author  YUE
	 * @date 2013-6-15 下午8:39:19
	 * @param hql
	 * @param objects
	 * @return
	 */
	private Query query(String hql , Object...objects)
	{
		Query query = query(hql);
		if(objects.length > 0)
			for (int i = 0; i < objects.length; i++)
				query.setParameter(i, objects[i]);
		return query;
	}

	/**
	 * 分页
	 * @param hql
	 * @param page
	 * @param size
	 * @return
	 * @date 2013-3-28 下午4:08:50
	 * @author yue
	 */
	private Query query(String hql, int page, int size)
	{
		return query(hql).setFirstResult((page - 1) * size).setMaxResults(size);
	}
	
	/**
	 * 
	 * @author  YUE
	 * @date 2013-6-25 下午5:50:38
	 * @param hql
	 * @return
	 */
	protected Map<String,Object> map(String hql)
	{
		return (Map<String, Object>) query(hql).list().get(0);
	}
	
	protected Map<String,Object> map(String hql,Map<String, Object> hqlMap)
	{
		return (Map<String, Object>) query(hql,hqlMap).list().get(0);
	}
	
	protected Map<String,Object> map(String hql,Object...objects)
	{
		return (Map<String, Object>) query(hql,objects).list().get(0);
	}
	
	/**
	 * 返回
	 * @author  YUE
	 * @date 2013-7-16 下午5:22:27
	 * @param hql
	 * @param objects
	 * @return
	 */
	protected List<Map<String,Object>> listMap(String hql,Object...objects)
	{
		return query(hql,objects).list();
	}
	protected List<Map<String,Object>> listMap(String hql,int maxResult,Object...objects)
	{
		return query(hql,objects).setMaxResults(maxResult).list();
	}
	protected List<Map<String,Object>> listMap(String hql,int page,int size,Object...objects)
	{
		return query(hql,page,size,objects).list();
	}
	
	/**
	 * 手动映射
	 * @author  YUE
	 * @param <E>
	 * @date 2013-9-5 下午2:44:42
	 * @param hql
	 */
	protected <E> List<E> scroll(String hql,ResultMapping<E> mapping)
	{
		return mapping.scroll(query(hql).scroll());
	}
	
	protected <E> List<E> scroll(String hql,int page,int size,ResultMapping<E> mapping)
	{
		ScrollableResults scroll = query(hql,page,size).scroll();
		List<E> list = mapping.scroll(scroll);
		scroll.close();
		return list;
	}
	
	protected <E> List<E> scroll(String hql,ResultMapping<E> mapping,Object...objects)
	{
		ScrollableResults scroll = query(hql,objects).scroll();
		List<E> list = mapping.scroll(scroll);
		scroll.close();
		return list;
	}
	
	protected <E> List<E> scroll(String hql,ResultMapping<E> mapping,int page,int size,Object...objects)
	{
		ScrollableResults scroll = query(hql,page,size,objects).scroll();
		List<E> list = mapping.scroll(scroll);
		scroll.close();
		return list;
	}
}